package org.xtext.runtime.formula;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.xtext.runtime.term.ITerm;
import org.xtext.runtime.term.Variable;
import org.xtext.runtime.util.Bindings;
import org.xtext.runtime.util.ILogicVisitor;

/**
 * Represents a Cartago property event.
 * 
 * @param type is a String that can be one of {added, changed, removed}
 * @param id is the id of artifact that generated the event (or a variable)
 * @param content is the content of the event
 * @author rem
 *
 */
public class CartagoPropertyEvent implements Event {
	public static final String ADDED = "added";
	public static final String REMOVED = "removed";
	public static final String UPDATED = "updated";
	
	private String type;
	private ITerm id;
	private Predicate formula;
	
	public CartagoPropertyEvent(String type, ITerm id, Predicate event) {
		this.type = type;
		this.id = id;
		this.formula = event;
	}

	public String signature() {
		return "@cpe:"+type+"/"+formula.signature();
	}
	
	public String toString() {
		return "@cartago(" + type + "," + id + "," + formula + ")";
	}
	
	public String type() {
		return type;
	}
	
	public ITerm id() {
		return id;
	}
	
	public Predicate content() {
		return formula;
	}

	@Override
	public CartagoPropertyEvent copy() {
		return new CartagoPropertyEvent(type, id.copy(), formula.copy());
	}

	@Override
	public Set<Variable> variables() {
		Set<Variable> variables = new HashSet<Variable>();
		if (id instanceof Variable) {
			variables.add((Variable) id); 
		}
		variables.addAll(formula.variables());
		return variables;
	}

	@Override
	public IFormula apply(Bindings bindings) {
		id = id.apply(bindings);
		formula = formula.apply(bindings);
		return this;
	}

	@Override
	public IFormula copy(Map<String, Variable> vars) {
		return new CartagoPropertyEvent(type, id.copy(vars), formula.copy(vars));
	}

	@Override
	public boolean hasFreeVariables() {
		if (id instanceof Variable && ((Variable) id).isFree()) return true; 
		return formula.hasFreeVariables();
	}

	@Override
	public Object accept(ILogicVisitor visitor) {
		return null;
	}

	@Override
	public Object source() {
		return null;
	}
}
